package com.github.chirspan.xaas.auth.web.api;

import com.alibaba.fastjson.JSONObject;
import com.github.chirspan.xaas.core.exception.BizException;
import com.github.chirspan.xaas.core.util.HeaderSecurityUtils;
import com.github.chirspan.xaas.security.service.AuthUserDetail;
import com.github.chirspan.xaas.security.util.SecurityUtils;
import com.github.chirspan.xaas.rbac.config.SecurityProperties;
import com.github.chirspan.xaas.rbac.model.RbacResource;
import com.github.chirspan.xaas.rbac.model.RbacUser;
import com.github.chirspan.xaas.rbac.service.IResourceService;
import com.github.chirspan.xaas.rbac.service.IRoleService;
import com.github.chirspan.xaas.rbac.service.IUserService;
import com.github.chirspan.xaas.core.rest.RestResult;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import io.swagger.annotations.Authorization;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.bcrypt.BCrypt;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.Arrays;

/**
 * @author ChenPan
 * @date 2018/7/6 16:44
 * description:
 */
@RestController
@RequestMapping("/auth")
@Api(value = "auth", description = "登录账户管理", tags = "auth")
@Slf4j
public class AuthController {

    @Autowired
    private IUserService userService;

    @Autowired
    private IRoleService roleService;

    @Autowired
    private IResourceService resourceService;

    @Autowired
    private SecurityProperties securityProperties;

    /**
     * 是否管理员
     *
     * @return
     */
    protected boolean isSuperAdmin() {
        return SecurityUtils.hasRole(securityProperties.getRoleSuperAdmin());
    }


    /**
     * 当前账户信息
     *
     * @return
     */
    @GetMapping("/user/profile")
    @ApiOperation(value = "当前账户信息", authorizations = {@Authorization(value = "apiKey")})
    public RestResult getUserProfile() {

        AuthUserDetail authUser = SecurityUtils.getCurrentUser();
        RbacUser user = userService.findUser(authUser.getUsername());

        JSONObject profile = new JSONObject();

        profile.put("user", user);

        profile.put("role", SecurityUtils.getAuthorities());
        profile.put("permission", resourceService.getStringPermissions(user.getUsername()));
        return RestResult.OK(profile);
    }

    @GetMapping("/user/role")
    @ApiOperation(value = "账户角色信息", authorizations = {@Authorization(value = "apiKey")})
    public RestResult getUserRole() {
        return RestResult.OK(SecurityUtils.getAuthorities());
    }

    @GetMapping("/user/permission")
    @ApiOperation(value = "账户权限信息", authorizations = {@Authorization(value = "apiKey")})
    public RestResult getUserPermission() {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        if (authentication == null) {
            return RestResult.OK(null);
        }
        return RestResult.OK(resourceService.getStringPermissions(authentication.getName()));
    }

    /**
     * 获取用户菜单信息
     *
     * @return
     */
    @GetMapping("/user/sysMenu")
    @ApiOperation(value = "账户菜单信息", authorizations = {@Authorization(value = "apiKey")})
    public RestResult getUserSysMenu(@RequestParam(value = "appIds", required = false) String[] appIds) {
        if (isSuperAdmin() && securityProperties.getAdminHasAllPermission()) {
            RbacResource cre = new RbacResource();
            cre.setResourceType("1");
            if (appIds != null && appIds.length > 0) {
                cre.setAppIds(Arrays.asList(appIds));
            }
            return RestResult.OK(resourceService.findResourcesTree(cre));
        }
        return RestResult.OK(resourceService.findUserSysResources(SecurityUtils.getCurrentUser().getUsername(),
                Arrays.asList(appIds)));
    }

    @PutMapping("/profile/passwd")
    @ApiOperation(value = "更改密码", authorizations = {@Authorization(value = "apiKey")})
    public RestResult updatePasswd(@ApiParam("旧密码") @RequestParam("oldPass") String oldPass,
                                   @ApiParam("新密码") @RequestParam("newPass") String newPass) {

        RbacUser oldUser = userService.findUser(SecurityUtils.getCurrentUser().getUsername());

        if (BCrypt.checkpw(oldPass, oldUser.getPassword())) {
            userService.updatePassword(SecurityUtils.getCurrentUser().getUsername(), newPass);
            return RestResult.OK(null);
        } else {
            throw new BizException("旧密码不正确");
        }
    }

    /**
     * 更新账户信息
     *
     * @param user
     * @param result
     * @return
     */
    @PutMapping("/profile")
    @ApiOperation(value = "更新账户信息", authorizations = {@Authorization(value = "apiKey")})
    public RestResult updateUser(@ApiParam("当前账户信息") @RequestBody @Validated RbacUser user, BindingResult result) {
        userService.updateUserProfile(user);
        return RestResult.OK(null);
    }

}
